
"""
Wind
A module to handle the fact that the wind isn't constant.
"""

import logging
from directions import *
from dice import *

class WindVector(object):
    """
    Represents the wind on any given turn (but only for that turn).
    """
    direction = North
    dir = North
    dist = 0
    log = logging.getLogger('pgame.engine.WindVector')
    def __str__(self):
        return '%s" %s' % (self.dist, str(self.dir).upper() )
    def __init__(self, distance=1, direction=North):
        self.dist = distance
        self.dir = direction
    def __getdir(self):
        return self.dir
    def __setdir(self, value):
        self.dir = value
    direction = property(__getdir, __setdir)

    def __getdist(self):
        return self.dist
    def __setdist(self, value):
        self.dist = value
    distance = property(__getdist, __setdist)


class WindGenerator(object):
    """
    Generates wind for each turn.
    """

    log = logging.getLogger('pgame.engine.WindGenerator')
    prevWind = None
    __inst = None

    weakWind = 0.5
    normalWind = 1.0
    strongWind = 1.75
    noWind = 0.0

    def __new__(cls):
        if cls.__inst is None:
            cls.__inst = self = super(cls, WindGenerator).__new__(cls)
            self.prevWind = None
        else:
            self = cls.__inst
        return self
    
    def getNextWind(self):
        """
        Returns the next wind. Doesn't track turns. Don't use unless you know what 
        you're doing.
        """
        # Yes, this function could be abbreviated considerably if I seperated
        # the rules for each prevWind.dist into their own functions. However,
        # function calls are expensive in Python, so I won't unless I have a
        # good reason otherwise.
        
        if self.prevWind is None:
            self.log.debug('Generating initial wind')
            self.prevWind = WindVector()
            return self.prevWind
        
        else:
            windChanges = dice1d6.roll() > 4
            if windChanges:
                self.log.debug('The wind changes this turn...')
                newWind = WindVector()
                roll = dice1d4.roll()
                deltaD = roll // 2
                sign = roll % 2
                # Previous "-1**sign * deltaD" was always negative.
                # Also "-1**(sign+1) * deltaD" was always negative.
                # And "(-1**(sign+1)) * deltaD" was always negative.
                # So here's the new sign, which works:
                if sign == 0:
                    deltaD *= -1
                newWind.dir = self.prevWind.dir + deltaD
                roll =  dice1d10.roll()
                if self.prevWind.dist == self.noWind:
                    #Return every other turn
                    if dice1d4.roll() > 2:
                        newWind.dist = self.weakWind
                        if dice1d4.roll() < 2:
                            newWind.dir = -newWind.dir
                    else:
                        newWind.dist = self.noWind
                
                if   self.prevWind.dist == self.weakWind:
                    # Every three turns, it'll switch to normal.
                    # If 0, die. Else, remain.
                    if roll % 3 == 1:
                        newWind.dist = self.normalWind
                    elif roll == 0:
                        newWind.dist = self.noWind
                    else:
                        newWind.dist = self.weakWind
                
                elif self.prevWind.dist == self.normalWind:
                    # Most of the time, no change.
                    # Equal chance of weak/strong.
                    newWind.dist = self.normalWind
                    roll = dice1d12.roll()
                    if roll % 4 == 3:
                        #Weak wind
                        newWind.dist = self.weakWind
                    elif roll % 4 == 2:
                        #Strong wind
                        newWind.dist = self.strongWind
                
                elif self.prevWind.dist == self.strongWind:
                    #Every three turns, switch to normal.
                    newWind.dist = self.strongWind
                    roll = dice1d12.roll()
                    if roll % 3 == 2:
                        newWind.dist = self.normalWind
            
                # Store the new wind.
                self.prevWind = newWind
                return self.prevWind
            
            elif not windChanges:
                return self.prevWind
            

if __name__ == '__main__':
    gen = WindGenerator()
    while raw_input('>') is not None:
        print gen.getNextWind()
    